﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Teigha.Core
{
	public class OdRxDictionary : OdRxObject, IDictionary<string, OdRxObject>, ICollection<KeyValuePair<string, OdRxObject>>, IEnumerable<KeyValuePair<string, OdRxObject>>, IEnumerable
	{
		[EditorBrowsable(EditorBrowsableState.Never)]
		public OdRxDictionary(IntPtr cPtr, bool cMemoryOwn) : base(GlobalsPINVOKE.OdRxDictionary_SWIGUpcast(cPtr), cMemoryOwn)
		{
			this.swigCPtr = new HandleRef(this, cPtr);
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static HandleRef getCPtr(OdRxDictionary obj)
		{
			if (obj != null)
			{
				return obj.swigCPtr;
			}
			return new HandleRef(null, IntPtr.Zero);
		}

		~OdRxDictionary()
		{
			this.Dispose();
		}

		public override void Dispose()
		{
			if (this.swigCPtr.Handle != IntPtr.Zero)
			{
				if (this.swigCMemOwn)
				{
					lock (this.locker)
					{
						if (this.swigCPtr.Handle != IntPtr.Zero && this.swigCMemOwn)
						{
							this.swigCMemOwn = false;
							GlobalsPINVOKE.delete_OdRxDictionary(this.swigCPtr);
						}
					}
					this.swigCMemOwn = false;
				}
				this.swigCPtr = new HandleRef(null, IntPtr.Zero);
			}
			GC.SuppressFinalize(this);
			base.Dispose();
		}

		public bool ContainsKey(string key)
		{
			return this.has(key);
		}

		public void Add(string key, OdRxObject value)
		{
			this.putAt(key, value);
		}

		public bool Remove(string key)
		{
			return this.remove(key) != null;
		}

		public bool TryGetValue(string key, out OdRxObject value)
		{
			value = this.getAt(key);
			return value != null;
		}

		public OdRxObject this[string key]
		{
			get
			{
				return this.getAt(key);
			}
			set
			{
				this.putAt(key, value);
			}
		}

		public void Add(KeyValuePair<string, OdRxObject> p)
		{
			this.putAt(p.Key, p.Value);
		}

		public void Clear()
		{
			List<string> list = new List<string>();
			OdRxDictionaryIterator odRxDictionaryIterator = this.newIterator();
			while (!odRxDictionaryIterator.done())
			{
				list.Add(odRxDictionaryIterator.getKey());
				odRxDictionaryIterator.next();
			}
			foreach (string key in list)
			{
				this.remove(key);
			}
		}

		public bool Contains(KeyValuePair<string, OdRxObject> p)
		{
			return this.has(p.Key) && OdRxObject.getCPtr(this.getAt(p.Key)).Handle == OdRxObject.getCPtr(p.Value).Handle;
		}

		public void CopyTo(KeyValuePair<string, OdRxObject>[] a, int N)
		{
			for (int i = N; i < a.Length; i++)
			{
				this.putAt(a[i].Key, a[i].Value);
			}
		}

		public bool Remove(KeyValuePair<string, OdRxObject> p)
		{
			return this.Remove(p.Key);
		}

		public bool IsReadOnly
		{
			get
			{
				return false;
			}
		}

		public int Count
		{
			get
			{
				return (int)this.numEntries();
			}
		}

		public ICollection<string> Keys
		{
			get
			{
				string[] array = new string[this.numEntries()];
				int num = 0;
				OdRxDictionaryIterator odRxDictionaryIterator = this.newIterator();
				while (!odRxDictionaryIterator.done())
				{
					array[++num] = odRxDictionaryIterator.getKey();
					odRxDictionaryIterator.next();
				}
				return array;
			}
		}

		public ICollection<OdRxObject> Values
		{
			get
			{
				OdRxObject[] array = new OdRxObject[this.numEntries()];
				int num = 0;
				OdRxDictionaryIterator odRxDictionaryIterator = this.newIterator();
				while (!odRxDictionaryIterator.done())
				{
					array[++num] = odRxDictionaryIterator.getObject();
					odRxDictionaryIterator.next();
				}
				return array;
			}
		}

		IEnumerator<KeyValuePair<string, OdRxObject>> IEnumerable<KeyValuePair<string, OdRxObject>>.GetEnumerator()
		{
			return new OdRxDictionary.OdRxDictionaryEnumerator(this);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new OdRxDictionary.OdRxDictionaryEnumerator(this);
		}

		public new static OdRxDictionary cast(OdRxObject pObj)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_cast(OdRxObject.getCPtr(pObj));
			OdRxDictionary result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject((OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = (OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = (OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public new static OdRxClass desc()
		{
			OdRxClass result = (OdRxClass)Teigha.Core.Helpers.odrxCreateObjectInternal(GlobalsPINVOKE.OdRxDictionary_desc(), false);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public new virtual OdRxClass isA()
		{
			OdRxClass result = (OdRxClass)Teigha.Core.Helpers.odrxCreateObjectInternal(GlobalsPINVOKE.OdRxDictionary_isA(this.swigCPtr), false);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public new virtual OdRxObject queryX(OdRxClass protocolClass)
		{
			OdRxObject result = Teigha.Core.Helpers.odrxCreateObjectInternal(GlobalsPINVOKE.OdRxDictionary_queryX(this.swigCPtr, OdRxClass.getCPtr(protocolClass)), false);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public static OdRxDictionary createObject()
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_createObject();
			OdRxDictionary result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject((OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = (OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = (OdRxDictionary)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual void reserve(uint minSize)
		{
			GlobalsPINVOKE.OdRxDictionary_reserve(this.swigCPtr, minSize);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public virtual OdRxObject getAt(string key)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_getAt__SWIG_0(this.swigCPtr, key);
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject getAt(uint id)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_getAt__SWIG_1(this.swigCPtr, id);
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject putAt(string key, OdRxObject pObject, out uint pRetId)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_putAt__SWIG_0(this.swigCPtr, key, OdRxObject.getCPtr(pObject), out pRetId);
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject putAt(string key, OdRxObject pObject)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_putAt__SWIG_1(this.swigCPtr, key, OdRxObject.getCPtr(pObject));
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject putAt(uint id, OdRxObject pObject)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_putAt__SWIG_2(this.swigCPtr, id, OdRxObject.getCPtr(pObject));
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual bool resetKey(uint id, string newKey)
		{
			bool result = GlobalsPINVOKE.OdRxDictionary_resetKey(this.swigCPtr, id, newKey);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject remove(string key)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_remove__SWIG_0(this.swigCPtr, key);
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxObject remove(uint id)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_remove__SWIG_1(this.swigCPtr, id);
			OdRxObject result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual bool has(string key)
		{
			bool result = GlobalsPINVOKE.OdRxDictionary_has__SWIG_0(this.swigCPtr, key);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual bool has(uint id)
		{
			bool result = GlobalsPINVOKE.OdRxDictionary_has__SWIG_1(this.swigCPtr, id);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual uint idAt(string key)
		{
			uint result = GlobalsPINVOKE.OdRxDictionary_idAt(this.swigCPtr, key);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual string keyAt(uint id)
		{
			string result = GlobalsPINVOKE.OdRxDictionary_keyAt(this.swigCPtr, id);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual uint numEntries()
		{
			uint result = GlobalsPINVOKE.OdRxDictionary_numEntries(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxDictionaryIterator newIterator(DictIterType iterType)
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_newIterator__SWIG_0(this.swigCPtr, (int)iterType);
			OdRxDictionaryIterator result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject((OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = (OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = (OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual OdRxDictionaryIterator newIterator()
		{
			MemoryManager memoryManager = MemoryManager.GetMemoryManager();
			MemoryTransaction currentTransaction = memoryManager.GetCurrentTransaction();
			IntPtr p = GlobalsPINVOKE.OdRxDictionary_newIterator__SWIG_1(this.swigCPtr);
			OdRxDictionaryIterator result;
			if (currentTransaction != null)
			{
				currentTransaction.AddObject((OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true));
				result = (OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, false);
			}
			else
			{
				result = (OdRxDictionaryIterator)Teigha.Core.Helpers.odrxCreateObjectInternal(p, true);
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public virtual bool isCaseSensitive()
		{
			bool result = GlobalsPINVOKE.OdRxDictionary_isCaseSensitive(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private object locker = new object();

		private HandleRef swigCPtr;

		public sealed class OdRxDictionaryEnumerator : IEnumerator<KeyValuePair<string, OdRxObject>>, IDisposable, IEnumerator
		{
			public OdRxDictionaryEnumerator(OdRxDictionary collection)
			{
				this.collectionRef = collection;
				this.iterator = this.collectionRef.newIterator();
				this.enumerationStarted = false;
			}

			public KeyValuePair<string, OdRxObject> Current
			{
				get
				{
					if (!this.enumerationStarted)
					{
						throw new InvalidOperationException("Enumeration not started.");
					}
					if (this.iterator.done())
					{
						throw new InvalidOperationException("Enumeration finished.");
					}
					return new KeyValuePair<string, OdRxObject>(this.iterator.getKey(), this.iterator.getObject());
				}
			}

			object IEnumerator.Current
			{
				get
				{
					return this.Current;
				}
			}

			public bool MoveNext()
			{
				if (this.enumerationStarted && !this.iterator.done())
				{
					this.iterator.next();
				}
				else
				{
					this.enumerationStarted = true;
				}
				return !this.iterator.done();
			}

			public void Reset()
			{
				this.enumerationStarted = false;
				this.iterator = this.collectionRef.newIterator();
			}

			public void Dispose()
			{
				this.collectionRef = null;
				this.iterator = null;
			}

			private OdRxDictionary collectionRef;

			private OdRxDictionaryIterator iterator;

			private bool enumerationStarted;
		}
	}
}
